package com.culture.config.core;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.culture.config.common.model.ResponseData;
import com.culture.config.common.util.ExceptionUtil;
import com.culture.config.common.util.ResourceUtil;
import com.culture.config.common.util.ResponseUtil;
import com.culture.config.constant.ErrorMessage;
import com.culture.config.model.AuthInfo;
import com.culture.config.model.MenuInfo;
import com.culture.config.service.AuthService;
import com.culture.config.util.AuthenticationUtil;

import lombok.extern.slf4j.Slf4j;
import springfox.documentation.annotations.ApiIgnore;

@Slf4j
@ApiIgnore
@RestController
@RequestMapping({"/auth"})
public class SecurityAuthController {	
	@Value("${spring.config.web.resource.path:/static/}")
	private String resourcePath;	
	@Autowired	
	private AuthService authService;
	@Autowired	
	private Swagger3Config swagger3Config;
	
	@GetMapping("/login.html")
	public void login(HttpServletRequest request,HttpServletResponse reponse) {
		ResourceUtil.writeClassResourceFile(reponse, resourcePath.concat("login.html"));		
	}
	
	@GetMapping("/default.html")
	public void index(HttpServletRequest request,HttpServletResponse reponse) {
		ResourceUtil.writeClassResourceFile(reponse, resourcePath.concat("default.html"));		
	}
	
	@GetMapping("/javascript/{fileName:.*}")
	public void javascript(@PathVariable(value="fileName",required=true)String fileName,
			HttpServletRequest request,HttpServletResponse reponse) {
		log.info(fileName);
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);		
		ResourceUtil.writeClassResourceFile(reponse, resourcePath.concat("javascript/").concat(fileName));	
	}
	
	@GetMapping("/javascript/{subPath}/{fileName:.*}")
	public void javascript2(@PathVariable(value="fileName",required=true)String fileName,
			@PathVariable(value="subPath",required=true)String subPath,
			HttpServletRequest request,HttpServletResponse reponse) {
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);
		String filePath = StringUtils.join(resourcePath,"javascript/",subPath,"/",fileName);
		if(StringUtils.equals(fileName, "service.js") || StringUtils.equals(fileName, "AppConfig.js")){
			ResourceUtil.writeClassResourceFile(reponse,filePath,this.authService.getServiceInfo());
			return;
		}		
		ResourceUtil.writeClassResourceFile(reponse, filePath);	
	}
	
	@GetMapping("/framepages/{fileName:.*}")
	public void framepages(@PathVariable(value="fileName",required=true)String fileName,
			HttpServletRequest request,HttpServletResponse reponse) {
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);
		ResourceUtil.writeClassResourceFile(reponse,resourcePath.concat("framepages/").concat(fileName));	
	}
	
	@GetMapping("/datapages/{fileName:.*}")
	public void datapages(@PathVariable(value="fileName",required=true)String fileName,
			HttpServletRequest request,HttpServletResponse reponse) {
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);		
		ResourceUtil.writeClassResourceFile(reponse,resourcePath.concat("datapages/").concat(fileName));	
	}
	
	@GetMapping("/stylesheets/{fileName:.*}")
	public void stylesheets(@PathVariable(value="fileName",required=true)String fileName,
			HttpServletRequest request,HttpServletResponse reponse) {
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);		
		ResourceUtil.writeClassResourceFile(reponse, resourcePath.concat("stylesheets/").concat(fileName));	
	}
	
	@GetMapping("/stylesheets/{subPath}/{fileName:.*}")
	public void stylesheets2(@PathVariable(value="fileName",required=true)String fileName,
			@PathVariable(value="subPath",required=true)String subPath,
			HttpServletRequest request,HttpServletResponse reponse) {
		ExceptionUtil.businessExceptionWhenTrue(StringUtils.isBlank(fileName), ErrorMessage.BAD_REQUEST);		
		ResourceUtil.writeClassResourceFile(reponse, resourcePath.concat("stylesheets/").concat(subPath).concat("/").concat(fileName));	
	}	
	
	@GetMapping("/error")
	public String error() {
		return "Login failed!";
	}
	
	@GetMapping("/logout")
	public void logout(HttpServletRequest request,HttpServletResponse reponse) {		
		try {
			AuthenticationUtil.logout(request);
			reponse.sendRedirect("./login.html");
		} catch (IOException e) {
			log.error("logout exception:",e);
		}
	}
	
	/**
	 * get authorized info
	 * @param request
	 * @return
	 */
	@GetMapping("/info")
	public ResponseData<AuthInfo> getAuthInfo(HttpServletRequest request) {		
		String outCrsfToken = AuthenticationUtil.validateCrsfToken(request);
		AuthInfo authInfo = this.authService.getAuthInfo();
		authInfo.setAuthToken(AuthenticationUtil.saveAuthToken(request));
		authInfo.addConfig("swagger",this.swagger3Config.getSwaggerPath(AuthenticationUtil.getCrsfTokenParamsPair(request)));		
		authInfo.addConfig(AuthenticationUtil.CRSF_TOKEN_NAME,outCrsfToken);		
		return ResponseUtil.success(authInfo);
	}
	
	/**
	 * get authorized info
	 * @param request
	 * @return
	 */
	@GetMapping("/menu.info")
	public ResponseData<MenuInfo> getMenuInfo(HttpServletRequest request) {		
		AuthenticationUtil.validateCrsfToken(request);
		AuthenticationUtil.validateAuthToken(request);
		MenuInfo menuInfo = this.authService.getMenuInfo();			
		return ResponseUtil.success(menuInfo);
	}
}
